#include "_report_.h"

historyData::historyData()
{
    data.day = 0;
    data.mon = 0;
    data.year = 0;
    count = 0;
    TradePrice = 0;
    SalePrice = 0;
}

void HistoryList::init()
{
    count  = 0;
    list =  new HistoryList;
    list->head = list->tail = 0;
}

void HistoryList::deinit()
{
    ListNode *i = list->head;
    ListNode *del_elem;

    while (i != NULL)
    {
        del_elem = i;
        i = i->next;
        del_elem->next = 0;
        delete del_elem;
    }
    list->head = list->tail = 0;
    delete list;
}

bool HistoryList::deserialization(char *line, historyData &data)
{

    char* _int = new char[sizeof(int)];
    char* _float = new char[sizeof(float)];

    for(unsigned int i = 0; i < sizeof(int); i++)
    {
        _int[i] = line[i];
    }
    data.data.day = *((int*)_int);

    for(unsigned int i = 0; i < sizeof(int); i++)
    {
        _int[i] = line[sizeof(int) + i];
    }
    data.data.mon = *((int*)_int);

    for(unsigned int i = 0; i < sizeof(int); i++)
    {
        _int[i] = line[2*sizeof(int) + i];
    }
    data.data.year = *((int*)_int);
    delete _int;


    for(unsigned int j = 0; j < sizeof(float); j++)
    {
        _float[j] = line[3*sizeof(int) + j];
    }
    data.count= *((float*)_float);

    for(unsigned int j = 0; j < sizeof(float); j++)
    {
        _float[j] = line[3*sizeof(int) + sizeof(float) + j];
    }
    data.TradePrice = *((float*)_float);

    for(unsigned int j = 0; j < sizeof(float); j++)
    {
        _float[j] = line[3*sizeof(int) + 2*sizeof(float) + j];
    }
    data.SalePrice = *((float*)_float);

    delete _float;
}

void HistoryList::pushBack(const historyData &data)
{
    ListNode *new_elem = new ListNode;

    new_elem->next = 0;
    new_elem->data = data;

    if (!list->head)
    {
        list->head = new_elem;
        list->tail = new_elem;
    }
    else
    {
        list->tail->next = new_elem;
        list->tail = new_elem;
    }
    count++;
}

int HistoryList::popBack(historyData *data)
{
    ListNode *i;

    if (list->head == NULL)
    {
        data = NULL;

        return -1;
    }

    count--;

    *data = list->tail->data;

    if (list->head == list->tail)
    {
        free(list->head);

        list->head = NULL;
        list->tail = NULL;

        return 0;
    }

    i = list->head;

    while (i->next != list->tail)
        i = i->next;

    free(list->tail);

    list->tail = i;

    return 0;
}

int HistoryList::countEntriesFile()
{
    FILE* f;
    int count = 0;
    f = fopen("bd_history.dat","rb");
    if(!f)
    {
        std::cout<<f<<std::endl;
        count = 0;
        return count;
    }
    char* line = new char[_historyData_size_];
    while(feof(f) == 0)
    {
        fread(line,_historyData_size_,1,f);
        count++;
    }
    count--;
    fclose(f);
    return count;

}

void HistoryList::print()
{
    ListNode *i = list->head;
    printf("\n| DATA       | COUNT               | TRADE PRICE         |  SALE               |\n");
    while (i != NULL)
    {
        printf("| %d%d.",(i->data.data.day)/10,(i->data.data.day) - (i->data.data.day/10*10));
        printf("%d%d.",(i->data.data.mon)/10,(i->data.data.mon) - (i->data.data.mon/10*10));
        printf("%d | ",(i->data.data.year));
        printf("%19.2f | ",i->data.count);
        printf("%19.2f | ",i->data.TradePrice);
        printf("%19.2f | ",i->data.SalePrice);
        std::cout<<i<< " -> "<<i->next<<std::endl;
        i = i->next;
    }
    printOther();
}

void HistoryList::printOther()
{
    int profit = 0,costs=0;
    ListNode *i = list->head;
    while (i != NULL)
    {
        costs += i->data.count * i->data.TradePrice;
        profit += i->data.count * i->data.SalePrice;
        i = i->next;
    }
    profit -=costs;
    printf("\nCost:\t%d and Profit\t%d\n",costs,profit);

}

bool HistoryList::save()
{
    FILE *f,*f2;
    int count = 0;
    f = fopen("bd_history.dat","ab");
    f2 = f;
    fclose(f2);
    if(!f)
    {
        std::cout << "Error open list\n";
        count = 0;
        return false;
    }
    int key = 0;

    ListNode *i = list->head;
    while (i != NULL)
    {
        saveOfOne(&i->data,key++);
        i = i->next;
    }
    return true;
}

bool HistoryList::load()
{
    FILE* f;
    f = fopen("bd_history.dat","rb");
    if (!f)
        return false;
    int counts = countEntriesFile();
    if(counts == 0)
        return false;
    historyData data;
    char* line = new char[_historyData_size_];

    for (int i = 0; i<counts; i++)
    {
        fread(line, _historyData_size_, 1 ,f);
        deserialization(line,data);
        pushBack(data);
    }

    return true;
}

void HistoryList::saveOfOne(historyData *data, int key)
{
    FILE *f;
    if(key == 0)
        f = fopen("bd_history.dat","wb");
    else
        f = fopen("bd_history.dat","ab");

    char* line = new char[_historyData_size_];
    char* psVar;

    //save date
    {
        psVar = (char*)&data->data.day;
        for(unsigned int i = 0; i < sizeof(int); i++)
        {
            line[i] = psVar[i];
        }

        psVar = (char*)&data->data.mon;
        for(unsigned int i = 0; i < sizeof(int); i++)
        {
            line[sizeof(int) + i] = psVar[i];
        }

        psVar = (char*)&data->data.year;
        for(unsigned int i = 0; i < sizeof(int); i++)
        {
            line[2*sizeof(int) + i] = psVar[i];
        }
    }

    //save other
    {
        psVar = (char*)&data->count;
        for(unsigned int i = 0; i < sizeof(float); i++)
        {
            line[3*sizeof(int) + i] = psVar[i];
        }

        psVar = (char*)&data->TradePrice;
        for(unsigned int i = 0; i < sizeof(float); i++)
        {
            line[3*sizeof(int) + sizeof(float) + i] = psVar[i];
        }

        psVar = (char*)&data->SalePrice;
        for(unsigned int i = 0; i < sizeof(float); i++)
        {
            line[3*sizeof(int) +2*sizeof(float) + i] = psVar[i];
        }
    }

    fwrite(line,_historyData_size_,1,f);

    fclose(f);

    delete line;
}

void testList()
{
    //функция для тестирования класса  односвязного списка
    //@wcd TODO: remove me pleease
    HistoryList *list = new HistoryList;
    list->init();
    historyData data;

    data.data.day = 1;

    data.data.mon = 12;
    data.SalePrice = 2000;
    data.data.year = 1000;
    list->pushBack(data);

    data.data.day = 2;
    list->pushBack(data);

    data.data.day  = 3;
    list->pushBack(data);

    list->save();
    list->print();
    list->deinit();
    list->init();
    list->print();
    list->load();
    list->print();
    list->deinit();
}
